package com.xjscrm.server.web.callback;

import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson.JSONObject;
import com.xjscrm.common.entity.WwCorp;
import com.xjscrm.common.enums.RedisCacheKeyEnum;
import com.xjscrm.common.utils.Tools;
import com.xjscrm.common.utils.ww.WXBizMsgCrypt;
import com.xjscrm.common.utils.ww.WwApiUtil;
import com.xjscrm.server.common.util.QyWxTools;
import com.xjscrm.server.constant.Const;
import com.xjscrm.server.dto.callback.ChangeExternalContactDto;
import com.xjscrm.server.service.common.CorpApplicationService;
import com.xjscrm.server.service.qywxcallback.QywxCallbackService;
import com.xjscrm.server.service.wwcorp.WwCorpService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.asn1.cms.PasswordRecipientInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 *
 */
@Controller
@RequestMapping("/callback/ww")
@Slf4j
public class WwCallbackController {

    @Autowired
    private QywxCallbackService qywxCallbackService;
    @Autowired
    private WwCorpService wwCorpService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private CorpApplicationService corpApplicationService;

    /**
     * 企业微信回调
     * 3.1 支持Http Get请求验证URL有效性
     * 3.2 支持Http Post请求接收业务数据
     *
     * @return
     */
    @RequestMapping(value = "/getCallBack/{merId}/{entId}", method = {RequestMethod.GET, RequestMethod.POST})
    public void companyWeChatChangeNotice(@PathVariable Long merId, @PathVariable String entId, HttpServletRequest request, HttpServletResponse response, @RequestBody(required = false) String body) throws IOException {
        Map<String, String[]> parameterMap = request.getParameterMap();
        String jsonString = JSONObject.toJSONString(parameterMap);
        log.info("企业微信回调参数：merId={}, entId={}, para={}, body={}", merId, entId, jsonString, body);

        if(merId == null || StringUtils.isBlank(entId)){
            return;
        }

        WwCorp wwCorp = wwCorpService.findWwCorp(merId, entId);
        if(wwCorp == null){
            return;
        }

        if(StringUtils.isBlank(wwCorp.getEntToken()) || StringUtils.isBlank(wwCorp.getEntId()) || StringUtils.isBlank(wwCorp.getEntAesKey())){
            return;
        }

        if (body == null) {
            String result = Tools.getStr(QyWxTools.verificationUrl(request, wwCorp.getEntToken(), wwCorp.getEntId(), wwCorp.getEntAesKey()));
            IoUtil.write(response.getOutputStream(), true, result.getBytes(StandardCharsets.UTF_8));
            return;
        }

        Map<String, String> resultMap = QyWxTools.getRequestParameter(request, body, wwCorp.getEntToken(), wwCorp.getEntId(), wwCorp.getEntAesKey());
        log.info("--修改标签推送数据Map={}", JSONObject.toJSONString(resultMap));
        if(resultMap != null ){
            String event = resultMap.get("Event");
            String changeType = resultMap.get("ChangeType");
            //事件的类型 ，编辑会员标签
            if("change_external_contact".equals(event) && "edit_external_contact".equals(changeType)){
                ChangeExternalContactDto changeExternalContactDto = JSONObject.parseObject(JSONObject.toJSONString(resultMap), ChangeExternalContactDto.class);
                if(changeExternalContactDto != null){
                    //直接处理
                    qywxCallbackService.handerQywxCallback(merId, entId, changeExternalContactDto.getExternalUserID());
                }
            }
        }

        return;
    }


    /**
     * 企业微信-应用管理-回调
     * 3.1 支持Http Get请求验证URL有效性
     * 3.2 支持Http Post请求接收业务数据
     *
     * @return
     */
    @RequestMapping(value = "/application", method = {RequestMethod.GET, RequestMethod.POST})
    public void applicationCallBack(HttpServletRequest request, HttpServletResponse response, @RequestBody(required = false) String body) throws IOException {
        Map<String, String[]> parameterMap = request.getParameterMap();
        String jsonString = JSONObject.toJSONString(parameterMap);
        log.info("企业微信应用管理回调参数：para={}, body={}", jsonString, body);

        String token = Const.WxworkApplication.token;
        String corpId = Const.WxworkApplication.corpId;
        String encodingAESKey = Const.WxworkApplication.encodingAESKey;
        String templateId = Const.WxworkApplication.templateId;

        if (body == null) {
            String result = Tools.getStr(QyWxTools.verificationUrl(request, token, corpId, encodingAESKey));
            IoUtil.write(response.getOutputStream(), true, result.getBytes(StandardCharsets.UTF_8));
            return;
        }

        Map<String, String> resultMap_corp = new HashMap<String, String>(16);
        resultMap_corp = QyWxTools.parseXmlToMap(body, resultMap_corp);
        corpId = resultMap_corp.get("ToUserName");
        Map<String, String> resultMap = QyWxTools.getRequestParameter(request, body, token, corpId, encodingAESKey);
        log.info("--企业微信应用管理推送数据Map={}", JSONObject.toJSONString(resultMap));
        if(resultMap != null ){
            //授权回调
            String infoType = resultMap.get("InfoType");
            if(StringUtils.isNotBlank(infoType)){
                if("suite_ticket".equals(infoType)){
                    log.info("企微应用推送ticket, data={}",JSONObject.toJSONString(resultMap));
                    String SuiteId = resultMap.get("SuiteId");
                    String SuiteTicket = resultMap.get("SuiteTicket");
                    corpApplicationService.corpApplicationSuiteTicket(SuiteId, SuiteTicket);
                }else if("create_auth".equals(infoType)){
                    log.info("企微应用授权通知, data={}",JSONObject.toJSONString(resultMap));
                    //处理企业应用授权
                    String SuiteId = resultMap.get("SuiteId");
                    String AuthCode = resultMap.get("AuthCode");
                    corpApplicationService.corpApplicationCreateAuth(SuiteId, AuthCode);
                }else if("reset_permanent_code".equals(infoType)){
                    log.info("企微应用重置永久码通知, data={}",JSONObject.toJSONString(resultMap));
                    //处理企业应用授权
                    String SuiteId = resultMap.get("SuiteId");
                    String AuthCode = resultMap.get("AuthCode");
                    corpApplicationService.corpApplicationResetPermanentCode(SuiteId, AuthCode);
                }else if("cancel_auth".equals(infoType)){
                    log.info("企微应用取消授权, data={}",JSONObject.toJSONString(resultMap));
                    //处理企业应用授权
                    String SuiteId = resultMap.get("SuiteId");
                    String AuthCorpId = resultMap.get("AuthCorpId");
                    corpApplicationService.corpApplicationCancelAuth(SuiteId, AuthCorpId);
                }
                IoUtil.write(response.getOutputStream(), true, "success".getBytes(StandardCharsets.UTF_8));
                return;
            }
        }

        IoUtil.write(response.getOutputStream(), true, "success".getBytes(StandardCharsets.UTF_8));
        return;

    }


    /**
     * 企业微信-应用管理-回调
     * 3.1 支持Http Get请求验证URL有效性
     * 3.2 支持Http Post请求接收业务数据
     *
     * @return
     */
    @RequestMapping(value = "/application/{authCorpId}", method = {RequestMethod.GET, RequestMethod.POST})
    public void applicationAuthCallBack(@PathVariable String authCorpId, HttpServletRequest request, HttpServletResponse response, @RequestBody(required = false) String body) throws IOException {
        Map<String, String[]> parameterMap = request.getParameterMap();
        String jsonString = JSONObject.toJSONString(parameterMap);
        log.info("企业微信应用管理回调参数：para={}, body={}", jsonString, body);

        String token = Const.WxworkApplication.token;
        String encodingAESKey = Const.WxworkApplication.encodingAESKey;
        String templateId = Const.WxworkApplication.templateId;
        String corpId = Const.WxworkApplication.corpId;

        if (body == null) {
            String result = Tools.getStr(QyWxTools.verificationUrl(request, token, authCorpId, encodingAESKey));
            IoUtil.write(response.getOutputStream(), true, result.getBytes(StandardCharsets.UTF_8));
            return;
        }

        Map<String, String> resultMap_suiteid = new HashMap<String, String>(16);
        resultMap_suiteid = QyWxTools.parseXmlToMap(body,resultMap_suiteid);
        String suiteid = resultMap_suiteid.get("ToUserName");

        Map<String, String> resultMap = QyWxTools.getRequestParameter(request, body, token, suiteid, encodingAESKey);
        log.info("--企业微信应用管理推送数据Map={}", JSONObject.toJSONString(resultMap));
        if(resultMap != null ){
            //变更事件回调
            String MsgType = resultMap.get("MsgType");
            String Event = resultMap.get("Event");

            if(StringUtils.isNotBlank(MsgType) && StringUtils.isNotBlank(Event) ){
                //事件的类型 ，编辑会员标签
                if("event".equals(MsgType) && "change_external_contact".equals(Event)){
                    ChangeExternalContactDto changeExternalContactDto = JSONObject.parseObject(JSONObject.toJSONString(resultMap), ChangeExternalContactDto.class);
                    if(changeExternalContactDto != null){
                        //通过应用代理来处理
                        corpApplicationService.handerUserCallback(changeExternalContactDto.getToUserName(), changeExternalContactDto.getExternalUserID());
                        //corpApplicationService.handerUserCallbackByWxwork(changeExternalContactDto.getToUserName(), changeExternalContactDto.getExternalUserID());
                    }
                }
                IoUtil.write(response.getOutputStream(), true, "success".getBytes(StandardCharsets.UTF_8));
                return;
            }
        }

        IoUtil.write(response.getOutputStream(), true, "success".getBytes(StandardCharsets.UTF_8));
        return;

    }



}
